package models

import (
	"cloudops/src/common"
	"fmt"
	"gorm.io/gorm"
	"gorm.io/gorm/clause"
	"regexp"
)

// 工单流程 审批流程模型
type Process struct {
	Model                 // 不用每次写ID 和 createAt了
	Name           string `json:"name" gorm:"uniqueIndex;type:varchar(100);comment:流程名称，支持使用通配符*进行模糊搜索"`
	UserID         uint
	FlowNodes      []FlowNode `json:"flowNodes"`
	FlowNodeStr    string     `json:"flowNodeStr" gorm:"-"`    // 流程节点字符串，方便前端使用
	Key            string     `json:"key" gorm:"-"`            // 流程Key，方便前端使用
	CreateUserName string     `json:"createUserName" gorm:"-"` // 创建人名称
}

// 工作流 审批流
type FlowNode struct {
	Model
	ProcessID         uint   `json:"processId"` // 属于哪个流程
	Type              string `json:"type" gorm:"comment: 起始节点 审批节点 执行节点 结束节点"`
	DefineUserOrGroup string `json:"defineUserOrGroup" gorm:"comment: 期望的人或者组 userName or RoleName"`
	ActualUser        string `json:"actualUser"  gorm:"-"`       // 实际审批的人或组
	OutPut            string `json:"outPut" gorm:"-"`            // 审批的结果 ，执行的输出
	EndTime           string `json:"endTime" gorm:"-"`           // 审批结束时间
	IsPassOrIsSuccess bool   `json:"isPassOrIsSuccess" gorm:"-"` // 审批的结果 或执行的结果
}

// 更新一个审批节点
func (obj *FlowNode) UpdateOneFlowNode() error {
	return DB.Where("id = ?", obj.ID).Updates(obj).Error
}

// 删除一个级联审批节点，以及它关联的数据
func (obj *FlowNode) DeleteOneFlowNode() error {
	return DB.Select(clause.Associations).Unscoped().Delete(&obj).Error
}

// 更新审批流关联的审批节点数据
func (obj *Process) UpdateFlowNodes(nodes []FlowNode) error {
	return DB.Model(obj).Association("FlowNodes").Replace(nodes)
}

// 创建流程
func (obj *Process) CreateProcess() error {
	return DB.Create(obj).Error
}

// 获取所有流程给前端做分页限制返回
func GetProcessAllWithLimitOffset(limit, offset int) (objs []*Process, err error) {
	err = DB.Preload("FlowNodes").Limit(limit).Offset(offset).Find(&objs).Error
	return
}

// 填充前端需要的数据
func (obj *Process) FillFrontAllData() {
	// 获取创建用户的 RealName
	dbUser, _ := GetUserById(int(obj.UserID))
	if dbUser != nil {
		obj.CreateUserName = dbUser.RealName
	}
	obj.Key = fmt.Sprintf("%d", obj.ID)

	// 正则表达式提取用户名
	usernamePattern := regexp.MustCompile(`用户@(\w+)`)

	// 构建 flowNodeStr
	for _, node := range obj.FlowNodes {
		// 提取用户名
		matches := usernamePattern.FindStringSubmatch(node.DefineUserOrGroup)
		realName := node.DefineUserOrGroup // 默认使用 DefineUserOrGroup
		if len(matches) > 1 {
			username := matches[1]
			dbUser, _ := GetUserByUserName(username)
			if dbUser != nil {
				realName = fmt.Sprintf("用户@%s", dbUser.RealName) // 替换为 RealName
			}
		}

		oneNode := fmt.Sprintf("%s : %s", common.FLOW_TYPE_MAP[node.Type], realName)
		if obj.FlowNodeStr != "" {
			obj.FlowNodeStr = fmt.Sprintf("%s -> %s", obj.FlowNodeStr, oneNode)
		} else {
			obj.FlowNodeStr = oneNode
		}
	}
}

// 获取流程数量总数
func GetProcessCount() int {
	var count int64
	DB.Table("processes").Count(&count)
	return int(count)
}

// 根据ID获取流程信息
func GetProcessById(id int) (*Process, error) {
	var obj Process
	err := DB.Where("id = ?", id).Preload("FlowNodes").First(&obj).Error
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, fmt.Errorf("process:%w 流程不存在")
		}
		return nil, fmt.Errorf("数据库查询失败：%w", err)
	}
	return &obj, nil
}

// 更新一个流程
func (obj *Process) UpdateOneProcess() error {
	return DB.Where("id = ?", obj.ID).Updates(obj).Error
}

// 删除一个流程，以及它关联的数据
func (obj *Process) DeleteOneProcess() error {
	return DB.Select(clause.Associations).Unscoped().Delete(&obj).Error
}

// 根据ID获取这个流程关联的工单模板
func GetWorkOrderTemplateByProcessId(processId int) (*WorkOrderTemplate, error) {
	var dbObj WorkOrderTemplate
	err := DB.Where("process_id = ?", processId).First(&dbObj).Error
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, fmt.Errorf("WorkOrderTemplate")
		}
		return nil, fmt.Errorf("数据库查询失败：%w", err)
	}
	return &dbObj, nil
}
